#!/bin/bash
#
####################################################
# SCRIPT DIR : 
#SCRIPT NAME : createFileSystem.sh
#     AUTHOR : dypt
#CREATE DATE : 
#   PLATFORM : Linux
#      USAGE :
################################################################
#input example: 
#/FileSystem01      10    user01    group01
#/FileSystem02      20    user02    group02
################################################################              
export TC_ALL=C
export LANG=en_US
################################################################
typeset -r SUCCESS=0             # Define the return code when successful
typeset -r WARNING=1             # Define the return code when an exception occurs
typeset -r ERROR=99              # Define the return code when error
typeset -i rc=0
typeset disks=""
typeset -A vglist
typeset -A vgnamelist
################################################################


RunCommd(){
       typeset sCommand_L=$1
       printf "[INFO] # ${sCommand_L} #\n"
       eval "${sCommand_L}";rc=$?
       if [ ${rc} -ne 0 ];then
              printf "[ERROR] # ${sCommand_L} # failed\n"
              return ${ERROR}
       fi
       printf "[INFO] # ${sCommand_L} # success\n"
       return ${SUCCESS}
}

# 创建pv
CreatePv(){
 for key in ${!vgnamelist[@]}; do
  sudo pvs | grep ${vgnamelist[${key}]}
  if [[ ! $? == 0 ]];then
   RunCommd "sudo pvcreate ${vgnamelist[${key}]}" || return ${ERROR}
  fi
  
 done
 return ${SUCCESS} 
}

# 新建，扩容vg
OperationVg(){
    for key in ${!vgnamelist[@]}; do
  sudo vgs | grep ${key}
  if [[ $? == 0 ]];then
   RunCommd "sudo vgextend ${key} ${vgnamelist[${key}]}" || return ${ERROR}
  else
   RunCommd "sudo vgcreate ${key} ${vgnamelist[${key}]}" || return ${ERROR}
  fi
  
 done
 return ${SUCCESS}
}

# 新建lv，文件系统
CreateFileSystem(){
       typeset sMountPoint_L=$1
       typeset sSize_L=$2
       typeset sUser_L=$3
       typeset sGroup_L=$4
       typeset sVgName=${5%+*}
       typeset sLvName_L=${5#*+}
       typeset sCommand_L=""
       # sLvName_L=$(echo "${sMountPoint_L}"|perl -pe 's#/#_#g')
       printf '[INFO] MountPoint=%s, Size=%s, User=%s, Group=%s\n' "${sMountPoint_L}" "${sSize_L}" "${sUser_L}" "${sGroup_L}"
       #mount point
       if [ ! -d "${sMountPoint_L}" ]; then
              sCommand_L="mkdir -p '${sMountPoint_L}'"
              RunCommd "sudo ${sCommand_L}" || return ${ERROR}
       fi
       for sCommand_L in "lvcreate -L '${sSize_L}G' -n '${sLvName_L}' ${sVgName} -y" \
              "mkfs.xfs '/dev/mapper/${sVgName}-${sLvName_L}'" \
              "sh -c \"echo '/dev/mapper/${sVgName}-${sLvName_L}      ${sMountPoint_L}  xfs   defaults  0     0' >> /etc/fstab\"" \
              "mount '${sMountPoint_L}'" \
              "chown '${sUser_L}:${sGroup_L}' '${sMountPoint_L}'"
       do
              RunCommd "sudo ${sCommand_L}" || return ${ERROR}
       done             
}

# 扩容lv，文件系统
ExtendFileSystem(){
       typeset sMountPoint_L=$1
       typeset sSize_L=$2
       typeset sUser_L=$3
       typeset sGroup_L=$4
       typeset sLvName_L=${5#*+}
       typeset sCommand_L=""
       
       printf '[INFO] MountPoint=%s, ExtendSize=%s, User=%s, Group=%s\n' "${sMountPoint_L}" "${sSize_L}" "${sUser_L}" "${sGroup_L}"
       # sLvName=`sudo lsblk -l  -o  NAME,TYPE,MOUNTPOINT | sort  | uniq | grep lvm | awk '{if ($3=="'${sMountPoint_L}'") print $1}'`   
       for sCommand_L in "lvextend -L +'${sSize_L}G' '${sLvName_L}' -y" \
              "xfs_growfs '${sLvName_L}' || sudo resize2fs '${sLvName_L}'"
       do
              RunCommd "sudo ${sCommand_L}" || return ${ERROR}
       done 

}
#实施前校验，
CheckVg(){
 typeset datavglistize=0
        typeset rootvglistize=0
 typeset disknums=0

 # 统计待扩容vg容量
 for key in ${!vglist[@]}; do
  set -- ${vglist[${key}]}
  if [[ ${key%%+*} == "datavg" ]]; then
   datavglistize=$((${datavglistize}+$2*1024*1024))
  else
   rootvglistize=$((${rootvglistize}+$2*1024*1024))
  fi
 done
 # 判断逻辑盘与容量是否满足扩容要求
 for key in ${!vgnamelist[@]}; do
  echo ${key}
  if [[ ${key} == "datavg" ]]; then
   echo $(sudo fdisk -s ${vgnamelist[${key}]})
   echo $datavglistize
   echo $rootvglistize
   if [[ $(sudo fdisk -s ${vgnamelist[${key}]}) -lt ${datavglistize} ]]; then
    printf "%s\n" "[ERROR] ${key} insufficient space, please check"
    return ${ERROR}
   fi
  else
   echo ${vgnamelist[${key}]}
   if [[ $(sudo fdisk -s ${vgnamelist[${key}]}) -lt ${rootvglistize} ]]; then
    printf "%s\n" "[ERROR] ${key} insufficient space, please check"
    return ${ERROR}
   fi
  fi
 done
 return ${SUCCESS}
 
    
}

#校验后实施
Ergodic(){ 
 for key in ${!vglist[@]}; do
  set -- ${vglist[$key]}
  #判断lv是否存在(01：不存在  02：存在)
  if [[ ${key##*+} == "01" ]]; then
   CreateFileSystem $1 $2 $3 $4 ${key%+*} || return ${ERROR}
  else
            ExtendFileSystem $1 $2 $3 $4 ${key%+*} || return ${ERROR}
  fi
  
 done
 return ${SUCCESS}


}

FormatPara(){
    typeset sLine_L=$1
 typeset vgname=""
 typeset lvpath=""
 typeset disknames=()
 
 # 格式化入参
 set -- ${sLine_L}
 # 获取待扩容lvpath
 lvpath=`sudo lsblk -l -p -o  NAME,TYPE,MOUNTPOINT | sort  | uniq | grep lvm | awk '{if ($NF=="'${1}'") print $1}'`
        if [[ -z ${lvpath}  ]]; then
  # 待新建目录存在则退出
  if [ -d "$1" ]; then
   printf '%s\n' "[ERROR] ${1} directory already exists, propose modify file name"
   return ${ERROR}
  fi
  vgnamelist["datavg"]=1
  # 构建待扩容vg参数
  # 判断lv是否存在( 01不存在，02存在)
  vglist["datavg+lv${1//\//_}+01"]=${sLine_L}
 else
  #获取vgname
  vgname=`sudo lvs -o vg_name,lv_path,lv_dm_path 2>/dev/null | grep ${lvpath} | awk '{print $1'}`
  vgnamelist[${vgname}]=2
  vglist["${vgname}+${lvpath}+02"]=${sLine_L}
     
 fi
     
 # 逻辑盘
 #read -a disknames < <(ls -l --time-style=posix-long-iso /dev/sd* | grep -E -v "[0-9]$" | grep `date +"%Y-%m-%d"`|awk '{print $NF}' | xargs)
 for key in $(ls -l /dev/sd* | grep -v "sda" |grep -E -v "[0-9]$" | awk '{print $NF}' | xargs); do
  sudo pvs | grep ${key}>/dev/null || disknames[${#disknames[@]}]=${key}
 done
 if [[ ${#disknames[@]} == 0 ]]; then
  printf "%s\n" "not found disk" 
 fi
 
 # 组合disk与vg
 if [[ ${#vgnamelist[*]} == 2 ]]; then
  for key in ${!vgnamelist[@]}; do
  if [[ ${key} == "datavg" ]]; then
   vgnamelist[${key}]=${disknames[1]}
  else
   vgnamelist[${key}]=${disknames[0]}
  fi
  done 
 else 
  vgnamelist[${!vgnamelist[@]}]=${disknames[0]}
  
 fi

 return ${SUCCESS}

}

#获取参数，并对参数进行整理
TaskMain(){
 if [ -z "$1" ];then
         printf "[INFO] no input, exit\n"
         return 0
 fi
 # 格式化入参
 while IFS="\t" read line; do
  [[ -z ${line} ]] && continue
  FormatPara "$line" || return ${WARNING}
 done< <(echo "$1")
 # 检查容量是否满足
 CheckVg || return ${WARNING}
 # 新建pv
 CreatePv || return ${WARNING}
 # 新建或扩容vg
 OperationVg || return ${WARNING}
 # 新建或扩容lv，文件系统
 Ergodic || return ${WARNING}

 return ${SUCCESS}

}


TaskMain "/opt/qfusion	200";rc=$?
exit ${rc}
